package com.gzx.plugin.ams.modular.reminder.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fhs.trans.service.impl.TransService;
import com.gzx.plugin.ams.modular.reminder.bo.GzxRenewalMattersAddOrEditBo;
import com.gzx.plugin.ams.modular.reminder.bo.GzxRenewalMattersQueryBo;
import com.gzx.plugin.ams.modular.reminder.entity.GzxRenewalMatters;
import com.gzx.plugin.ams.modular.reminder.entity.GzxRenewalNotice;
import com.gzx.plugin.ams.modular.reminder.mapper.GzxRenewalMattersMapper;
import com.gzx.plugin.ams.modular.reminder.mapper.GzxRenewalNoticeMapper;
import com.gzx.plugin.ams.modular.reminder.service.GzxRenewalService;
import com.gzx.plugin.ams.modular.reminder.vo.GzxRenewalMattersVo;
import com.gzx.plugin.ams.modular.utils.AmsSmsUtil;
import com.gzx.plugin.tjzy.modular.caffeine.UserCaffeine;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.consts.GzxTenantConstant;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.common.util.MapstructUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.apache.commons.lang.StringEscapeUtils.escapeSql;

/**
 * @author zjt
 * @description
 * @date 2025/6/24 09:12
 */
@DS("ams")
@Service
@RequiredArgsConstructor
public class GzxRenewalServiceImpl implements GzxRenewalService {

    private final GzxRenewalMattersMapper renewalMattersMapper;

    private final GzxRenewalNoticeMapper renewalNoticeMapper;

    private final TransService transService;

    private final UserCaffeine userCaffeine;

    /**
     * 分页查询续费事项
     *
     * @param renewalMattersQueryBo
     * @return
     */
    @Override
    public Page<GzxRenewalMattersVo> pageList(GzxRenewalMattersQueryBo renewalMattersQueryBo) {
        Page<GzxRenewalMattersVo> pageResult = renewalMattersMapper.selectVoPage(new Page<>(renewalMattersQueryBo.getCurrent(), renewalMattersQueryBo.getSize()),
                Wrappers.<GzxRenewalMatters>lambdaQuery()
                        .orderByDesc(GzxRenewalMatters::getId));
        if (CollectionUtil.isNotEmpty(pageResult.getRecords())) {
            List<Long> mattersIdList = pageResult.getRecords().stream()
                    .map(vo -> Long.parseLong(vo.getId()))
                    .toList();
            List<GzxRenewalNotice> renewalNoticeList = renewalNoticeMapper.selectList(Wrappers.<GzxRenewalNotice>lambdaQuery().in(GzxRenewalNotice::getMatterId, mattersIdList));
            if (CollectionUtil.isNotEmpty(renewalNoticeList)) {
                Map<String, List<String>> mattersUserMap = renewalNoticeList.stream()
                        .collect(Collectors.groupingBy(
                                s -> String.valueOf(s.getMatterId()),
                                Collectors.mapping(
                                        notice -> String.valueOf(notice.getUserId()),
                                        Collectors.toList())));
                pageResult.getRecords().forEach(s -> s.setUserIdList(mattersUserMap.get(s.getId())));
            }
        }
        return pageResult;
    }

    /**
     * 增加续费事项
     *
     * @param renewalMattersAddOrEditBo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertMatters(GzxRenewalMattersAddOrEditBo renewalMattersAddOrEditBo) {
        //入主库
        GzxRenewalMatters renewalMatters = MapstructUtils.convert(renewalMattersAddOrEditBo, GzxRenewalMatters.class);
        renewalMattersMapper.insert(renewalMatters);
        saveNotices(renewalMattersAddOrEditBo, renewalMatters);
    }

    /**
     * 修改续费事项
     *
     * @param renewalMattersAddOrEditBo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMatters(GzxRenewalMattersAddOrEditBo renewalMattersAddOrEditBo) {
        GzxRenewalMatters renewalMatters = MapstructUtils.convert(renewalMattersAddOrEditBo, GzxRenewalMatters.class);
        renewalMattersMapper.updateById(renewalMatters);
        renewalNoticeMapper.delete(Wrappers.<GzxRenewalNotice>lambdaUpdate().eq(GzxRenewalNotice::getMatterId, renewalMatters.getId()));
        saveNotices(renewalMattersAddOrEditBo, renewalMatters);
    }

    /**
     * 删除续费事项
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        renewalMattersMapper.deleteById(id);
        renewalNoticeMapper.delete(Wrappers.<GzxRenewalNotice>lambdaUpdate().eq(GzxRenewalNotice::getMatterId, id));
    }

    /**
     * 续费提醒
     */
    @Override
    public void renewalNotice() {
        List<GzxRenewalNotice> renewalNoticeList = renewalNoticeMapper.selectList(
                Wrappers.<GzxRenewalNotice>lambdaQuery()
                        .eq(GzxRenewalNotice::getNoticeDate, CommonDateUtil.getTodayStr())
                        .eq(GzxRenewalNotice::getIsNotice, 0));
        if (CollectionUtil.isNotEmpty(renewalNoticeList)) {
            List<Long> matterIdList = renewalNoticeList.stream().map(GzxRenewalNotice::getMatterId).toList();
            List<GzxRenewalMattersVo> renewalMattersVoList = renewalMattersMapper.selectVoBatchIds(matterIdList);
            transService.transMore(renewalMattersVoList);
            Map<String, GzxRenewalMattersVo> renewalMattersMap = renewalMattersVoList.stream()
                    .collect(Collectors.toMap(
                            GzxRenewalMattersVo::getId,
                            Function.identity()));
            Map<String, JSONObject> userMap = userCaffeine.getUserMapByTenantId(GzxTenantConstant.GZX_TENANT_ID);
            for (GzxRenewalNotice renewalNotice : renewalNoticeList) {
                if (renewalMattersMap.containsKey(String.valueOf(renewalNotice.getMatterId()))) {
                    GzxRenewalMattersVo renewalMattersVo = renewalMattersMap.get(String.valueOf(renewalNotice.getMatterId()));
                    StringBuilder sb = new StringBuilder(renewalMattersVo.getCreateUserName())
                            .append("，您好，从")
                            .append(renewalMattersVo.getProvider())
                            .append("购买的")
                            .append(renewalMattersVo.getType())
                            .append(":")
                            .append(renewalMattersVo.getName())
                            .append("，")
                            .append("将于")
                            .append(renewalMattersVo.getEndDate())
                            .append("到期，")
                            .append("续费金额为：")
                            .append(renewalMattersVo.getRenewalFee())
                            .append("，请及时充值或者续费");
                    //发送短信通知
                    if (userMap.containsKey(String.valueOf(renewalNotice.getUserId()))) {
                        JSONObject userJson = userMap.get(String.valueOf(renewalNotice.getUserId()));
                        String phone = userJson.getStr("phone");
                        if (StringUtils.isNotBlank(phone)) {
                            AmsSmsUtil.sendNoticeSms(phone, sb.toString());
                        }
                    }
                }
                //设置为已通知
                renewalNotice.setIsNotice(1);
                renewalNoticeMapper.updateById(renewalNotice);
            }
        }
    }

    private void saveNotices(GzxRenewalMattersAddOrEditBo renewalMattersAddOrEditBo, GzxRenewalMatters renewalMatters) {
        List<GzxRenewalNotice> renewalNoticeList = getGzxRenewalNotices(renewalMattersAddOrEditBo, renewalMatters);
        //构建新增SQL
        String currentDate = CommonDateUtil.getCurrentTimeStr();
        String sql = renewalNoticeList.stream()
                .map(s -> String.format("(%s,%s,'%s',%s,'%s','%s','%s','%s')",
                        escapeSql(String.valueOf(s.getMatterId())),
                        escapeSql(String.valueOf(s.getUserId())),
                        escapeSql(s.getNoticeDate()),
                        escapeSql(s.getTenantId()),
                        escapeSql(s.getCreateUser()),
                        escapeSql(currentDate),
                        escapeSql(s.getUpdateUser()),
                        escapeSql(currentDate)))
                .collect(Collectors.joining(", "));
        renewalNoticeMapper.insertBatch(sql);
    }

    @NotNull
    private static List<GzxRenewalNotice> getGzxRenewalNotices(GzxRenewalMattersAddOrEditBo renewalMattersAddOrEditBo, GzxRenewalMatters renewalMatters) {
        String noticeDate = CommonDateUtil.getDateBeforeOrAfterDays(renewalMatters.getEndDate(), -renewalMatters.getNoticeDate());
        List<String> dateStrList = CommonDateUtil.getDatesBetween(noticeDate, renewalMatters.getEndDate());
        List<Long> userIdList = renewalMattersAddOrEditBo.getUserIdList();
        List<GzxRenewalNotice> renewalNoticeList = new ArrayList<>();
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        for (Long userId : userIdList) {
            for (String date : dateStrList) {
                GzxRenewalNotice renewalNotice = new GzxRenewalNotice();
                renewalNotice.setUserId(userId);
                renewalNotice.setMatterId(renewalMatters.getId());
                renewalNotice.setNoticeDate(date);
                renewalNotice.setCreateUser(loginUser.getId());
                renewalNotice.setUpdateUser(loginUser.getId());
                renewalNoticeList.add(renewalNotice);
            }
        }
        return renewalNoticeList;
    }
}
